package com.haohan.cloud.scm.purchase.core.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.haohan.cloud.scm.api.constant.enums.common.TaskStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.purchase.LendingTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.purchase.PurchaseStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.supply.PdsOfferStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.supply.ShipStatusEnum;
import com.haohan.cloud.scm.api.purchase.entity.LendingRecord;
import com.haohan.cloud.scm.api.purchase.entity.PurchaseOrderDetail;
import com.haohan.cloud.scm.api.purchase.entity.PurchaseTask;
import com.haohan.cloud.scm.api.purchase.req.ConfirmGoodsReq;
import com.haohan.cloud.scm.api.supply.entity.OfferOrder;
import com.haohan.cloud.scm.api.supply.req.OfferOrderReq;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.purchase.core.IScmPurchaseDetailService;
import com.haohan.cloud.scm.purchase.service.LendingRecordService;
import com.haohan.cloud.scm.purchase.service.PurchaseOrderDetailService;
import com.haohan.cloud.scm.purchase.service.PurchaseTaskService;
import com.haohan.cloud.scm.purchase.utils.ScmPurchaseUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * @author dy
 * @date 2019/8/8
 */
@Service
@AllArgsConstructor
public class ScmPurchaseDetailServiceImpl implements IScmPurchaseDetailService {

    private final PurchaseOrderDetailService purchaseOrderDetailService;
    private final PurchaseTaskService purchaseTaskService;
    private final LendingRecordService lendingRecordService;
    private final ScmPurchaseUtils scmPurchaseUtils;

    /**
     * 揽货确认
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmGoods(ConfirmGoodsReq req) {
        String pmId = req.getPmId();
        // 采购任务 执行中
        QueryWrapper<PurchaseTask> queryTask = new QueryWrapper<>();
        queryTask.lambda()
                .eq(PurchaseTask::getPmId, pmId)
                .eq(PurchaseTask::getTaskStatus, TaskStatusEnum.doing)
                .eq(PurchaseTask::getId, req.getTaskId());
        PurchaseTask task = purchaseTaskService.getOne(queryTask);
        if (null == task) {
            throw new ErrorDataException("采购任务有误");
        }
        String detailSn = task.getPurchaseDetailSn();
        // 采购明细单
        QueryWrapper<PurchaseOrderDetail> queryDetail = new QueryWrapper<>();
        queryDetail.lambda()
                .eq(PurchaseOrderDetail::getPmId, pmId)
                .eq(PurchaseOrderDetail::getPurchaseStatus, PurchaseStatusEnum.stockUp)
                .eq(PurchaseOrderDetail::getPurchaseDetailSn, detailSn);
        PurchaseOrderDetail detail = purchaseOrderDetailService.getOne(queryDetail);
        if (null == detail) {
            throw new ErrorDataException("采购单明细有误");
        }
        // 报价单 修改 已接收 实际数量
        OfferOrderReq orderReq = new OfferOrderReq();
        orderReq.setPmId(pmId);
        orderReq.setSupplierId(detail.getSupplierId());
        orderReq.setPurchaseDetailSn(detailSn);
        orderReq.setStatus(PdsOfferStatusEnum.bidding);
        OfferOrder offerOrder = scmPurchaseUtils.fetchOfferOrder(orderReq);

        OfferOrder updateOffer = new OfferOrder();
        updateOffer.setId(offerOrder.getId());
        updateOffer.setShipStatus(ShipStatusEnum.receiveCargo);
        // 数量不等时修改
        BigDecimal realBuyNum = req.getRealBuyNum();
        if (realBuyNum.compareTo(offerOrder.getBuyNum()) != 0) {
            updateOffer.setBuyNum(realBuyNum);
            String remarks = "|原需求采购数量:" + offerOrder.getBuyNum() + "|";
            if (StrUtil.isNotEmpty(offerOrder.getRemarks())) {
                remarks = offerOrder.getRemarks() + remarks;
            }
            updateOffer.setRemarks(remarks);
        }
        // 设置金额
        BigDecimal otherAmount = req.getOtherAmount();
        otherAmount = (null == otherAmount) ? BigDecimal.ZERO : otherAmount;
        BigDecimal total = realBuyNum.multiply(offerOrder.getDealPrice()).add(otherAmount);
        updateOffer.setOtherAmount(otherAmount);
        updateOffer.setTotalAmount(total);
        scmPurchaseUtils.updateOfferOrder(updateOffer);
        // 采购明细单 修改 采购状态/实际采购数量/揽货时间/揽货方式/付款方式/请款类型
        PurchaseOrderDetail updateDetail = new PurchaseOrderDetail();
        modifyDetail(req, updateDetail);
        updateDetail.setId(detail.getId());
        purchaseOrderDetailService.updateById(updateDetail);

        PurchaseTask updateTask = new PurchaseTask();
        updateTask.setId(task.getId());
        updateTask.setActionTime(LocalDateTime.now());
        updateTask.setActionDesc(req.getActionDesc());
        purchaseTaskService.updateById(updateTask);
        return true;
    }

    /**
     * 采购明细单 修改 采购状态/实际采购数量/揽货时间/揽货方式/付款方式/请款类型
     *
     * @param req
     * @param detail
     */
    private void modifyDetail(ConfirmGoodsReq req, PurchaseOrderDetail detail) {
        detail.setPurchaseStatus(PurchaseStatusEnum.haveSales);
        detail.setRealBuyNum(req.getRealBuyNum());
        detail.setReceiveTime(LocalDateTime.now());
        detail.setReceiveType(req.getReceiveType());
        detail.setPayType(req.getPayType());
        // 需请款时 请款单关联 采购明细
        LendingTypeEnum lendingType = req.getLendingType();
        if (lendingType == LendingTypeEnum.needLending) {
            QueryWrapper<LendingRecord> query = new QueryWrapper<>();
            query.lambda()
                    .eq(LendingRecord::getLendingSn, req.getLendingSn())
                    .eq(LendingRecord::getPmId, req.getPmId());
            LendingRecord lendingRecord = lendingRecordService.getOne(query, false);
            if (null == lendingRecord) {
                lendingType = LendingTypeEnum.noLending;
            } else {
                LendingRecord update = new LendingRecord();
                update.setId(lendingRecord.getId());
                update.setPurchaseDetailSn(detail.getPurchaseDetailSn());
                lendingRecordService.updateById(update);
            }
        } else {
            lendingType = LendingTypeEnum.noLending;
        }
        detail.setLendingType(lendingType);
    }


}
